package com.utils;/**
 * @AUTHOR: 我是章璐锋憨憨
 * @Data:
 * @Version:
 */

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;

/**
 * @outhor RD
 * 2021/12/8
 */
public class DSUtil {
    private static DataSource ds = null;

    static {
        Properties p = new Properties();
        try {
            p.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
            ds = BasicDataSourceFactory.createDataSource(p);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConn() {
        try {
            return ds.getConnection();
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }
        return null;
    }

    public static void close(Statement st, Connection conn) {
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    public static void close(PreparedStatement ps, Connection conn) {
        try {
            if (ps != null) {
                ps.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    public static void close(ResultSet rs, PreparedStatement ps, Connection conn) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            try {
                if (ps != null) {
                    ps.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally {
                try {
                    if (conn != null) {
                        conn.close();
                    }
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }

    /**
     * 增删改工具类抽取
     *
     * @param sql
     * @param args
     * @return
     */
    public static int execute(String sql, Object... args) {
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            // 1. 加载驱动
            // 2. 获取连接对象
            conn = DSUtil.getConn();
            // 3. 获取执行sql语句对象
            ps = conn.prepareStatement(sql);
            for (int i = 1; i <= args.length; i++) {
                ps.setObject(i, args[i - 1]);
            }
            // 4. 执行sql语句
            return ps.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 5. 释放资源  先开后关
            DSUtil.close(ps, conn);
        }
        return 0;
    }

//    public static <T> List<T> query(String sql, Class<T> clazz, Object... args) {
//        Connection conn = null;
//        PreparedStatement ps = null;
//        ResultSet rs = null;
//        List<T> list = new ArrayList<>();
//        T t;
//        try {
//            conn = DSUtil.getConn();
//            ps = conn.prepareStatement(sql);
//            for (int i = 1; i <= args.length; i++) {
//                ps.setObject(i, args[i - 1]);
//            }
//            rs = ps.executeQuery();
//            while (rs.next()) {
//                t = clazz.newInstance();
//                Field[] df = clazz.getDeclaredFields();
//                Method[] dm = clazz.getDeclaredMethods();
//                for (Field field : df) {
//                    Object obj = rs.getObject(field.getName());
//                    for (Method method : dm) {
//                        String mname = method.getName().substring(3);
//                        if (method.getName().startsWith("set") && (mname.substring(0, 1).toLowerCase() + mname.substring(1)).equals(field.getName())) {
//                            method.invoke(t, obj);
//                        }
//                    }
//                }
//                list.add(t);
//            }
//            return list;
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            DSUtil.close(rs, ps, conn);
//        }
//        return list;
//    }

    /**
     *
     * @param sql
     *      sql语句
     * @param clazz
     *      类反射对象
     * @param args
     *      sql语句占位符中的参数
     * @param <T>
     *      泛型
     * @return
     *      泛型对应的list集合
     */
    public static <T> List<T> query(String sql, Class<T> clazz, Object... args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<T> list = new ArrayList<>();
        try {
            conn = DSUtil.getConn();
            ps = conn.prepareStatement(sql);
            for (int i = 1; i <= args.length; i++) {
                ps.setObject(i, args[i - 1]);
            }
            rs = ps.executeQuery();
            while (rs.next()) {
                T t = clazz.newInstance();
                HashMap<String, Object> hm = new HashMap<>();
                ResultSetMetaData rsm = rs.getMetaData();
                for (int i = 1; i <= rsm.getColumnCount(); i++) {
                    hm.put(rsm.getColumnLabel(i), rs.getObject(rsm.getColumnLabel(i)));
                }
                BeanUtils.populate(t, hm);
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DSUtil.close(rs, ps, conn);
        }
        return list;
    }
}
